package com.android.systemui.qs.tiles;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.database.ContentObserver;
import android.os.AsyncTask;
import android.os.Handler;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.quicksettings.Tile;
import android.telecom.TelecomManager;
import android.telephony.PhoneStateListener;
import android.telephony.PrimarySubManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.UniSettings;
import android.util.Log;
import android.widget.Switch;

import com.android.internal.telephony.RILConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.R;
import com.android.systemui.plugins.qs.QSIconView;
import com.android.systemui.plugins.qs.QSTile.BooleanState;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.qs.tileimpl.QSTileImpl;

/** Quick settings tile: Lte **/
public class LteServiceTile extends QSTileImpl<BooleanState> {
    private TelephonyManager mTelephonyManager;
    private boolean mListening;
    private boolean mLteEnabled;
    public static final int QS_LTESERVICE = 948;
    private int mServiceForPhone = 0;
    private final ContentObserver mObserver;

    public LteServiceTile(QSHost host) {
        super(host);
        mTelephonyManager = TelephonyManager.from(mContext);
        mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        mObserver = new ContentObserver(new Handler()) {
            @Override
            public void onChange(boolean selfChange) {
                Log.d(TAG,"onChange");
                refreshState();
            }
        };
    }

    public LteServiceTile(QSHost host, int phoneId) {
        this(host);
        mServiceForPhone = phoneId;
    }

    /* UNISOC: Modify for bug1335095 @{ */
    public void unregisterListen() {
        if (mTelephonyManager != null) {
            mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
        }
    }
    /* @} */

    @Override
    public BooleanState newTileState() {
        return new BooleanState();
    }

    @Override
    public void handleSetListening(boolean listening) {
        super.handleSetListening(listening);
        if (mListening == listening) {
            return;
        }
        mListening = listening;
        if (listening) {
            final IntentFilter filter = new IntentFilter();
            filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
            filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
            mContext.registerReceiver(mReceiver, filter);
            int defaultDataSubId;
            if (isSupportDualLTE()) {
                defaultDataSubId = getSubId();
            } else {
                defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
            }
            mContext.getContentResolver().registerContentObserver(Global.getUriFor(
                Global.PREFERRED_NETWORK_MODE + defaultDataSubId), true, mObserver);
        } else {
            mContext.unregisterReceiver(mReceiver);
            mContext.getContentResolver().unregisterContentObserver(mObserver);
        }
    }

    @Override
    protected void handleLongClick() {
    }

    @Override
    public Intent getLongClickIntent() {
        return new Intent();
    }

    @Override
    protected void handleClick() {
        /* UNISOC: Add for Bug 947650 @{ */
        if (!isNetworkOptionAllowed()) {
            Log.d(TAG, "handleClick---is not Allowed Network Option");
            return;
        }
        /* @} */
        if (getState().state == Tile.STATE_UNAVAILABLE) {
            return;
        } else {
            new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... args) {
                    setLteEnabled();
                    return null;
                }
            }.execute();
        }
    }

    /* UNISOC: Add for Bug 947650 @{ */
    private boolean isNetworkOptionAllowed() {
        return Settings.Global.getInt(mContext.getContentResolver(),
                UniSettings.UniGlobal.RESTRICT_NETWORK_TYPE + 1, 0) == 0;
    }
    /* @} */

    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            if(state != TelephonyManager.CALL_STATE_OFFHOOK){
                refreshState();
            }
        };
    };

    private void setLteEnabled() {
        Log.d(TAG, "setLteEnabled: " + !mState.value);
        mLteEnabled = !mState.value;
        int defaultDataSubId;
        if (isSupportDualLTE()) {
            defaultDataSubId = getSubId();
        } else {
            defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
        }
        if (SubscriptionManager.isValidSubscriptionId(defaultDataSubId)) {
            mTelephonyManager.setPreferredNetworkType(defaultDataSubId,
                    mLteEnabled ? RILConstants.NETWORK_MODE_LTE_GSM_WCDMA : RILConstants.NETWORK_MODE_WCDMA_PREF);
        }
    }

    private boolean getLteEnabled() {
        int defaultDataSubId;
        if (isSupportDualLTE()) {
            defaultDataSubId = getSubId();
        } else {
            defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
        }
        int settingsNetworkMode = android.provider.Settings.Global.getInt(
                mContext.getContentResolver(),
                android.provider.Settings.Global.PREFERRED_NETWORK_MODE + defaultDataSubId,
                RILConstants.PREFERRED_NETWORK_MODE);
        boolean lteEnable = (settingsNetworkMode == RILConstants.NETWORK_MODE_LTE_GSM_WCDMA
                || settingsNetworkMode == RILConstants.NETWORK_MODE_LTE_ONLY);
        return lteEnable;
    }

    @Override
    public CharSequence getTileLabel() {
        if (isSupportDualLTE()) {
            if (mServiceForPhone == 0) {
                return mContext.getString(R.string.quick_settings_lte1_service_label);
            } else if (mServiceForPhone == 1) {
                return mContext.getString(R.string.quick_settings_lte2_service_label);
            }
        }
        return mContext.getString(R.string.quick_settings_lte_service_label);
    }

    private Icon getDualLTETileIcon() {
        if (mServiceForPhone == 0) {
            return ResourceIcon.get(R.drawable.ic_qs_4g1_ex);
        } else if (mServiceForPhone == 1) {
            return ResourceIcon.get(R.drawable.ic_qs_4g2_ex);
        }
        return null;
    }

    @Override
    protected void handleUpdateState(BooleanState state, Object arg) {
        int defaultDataSubId;
        int phoneId = mServiceForPhone;
        boolean simAvailable;
        if (isSupportDualLTE()) {
            state.label = getTileLabel();
            defaultDataSubId = getSubId();
            simAvailable = ((SubscriptionManager.getSimStateForSlotIndex(phoneId)
                    == TelephonyManager.SIM_STATE_READY)
                    || (SubscriptionManager.getSimStateForSlotIndex(phoneId)
                    == TelephonyManager.SIM_STATE_LOADED))
                    && SubscriptionManager.isValidSubscriptionId(defaultDataSubId);
        } else {
            state.label = mContext.getString(R.string.quick_settings_lte_service_label);
            defaultDataSubId = SubscriptionManager.getDefaultDataSubscriptionId();
            phoneId = SubscriptionManager.getPhoneId(defaultDataSubId);
            simAvailable = ((SubscriptionManager.getSimStateForSlotIndex(phoneId)
                    == TelephonyManager.SIM_STATE_READY)
                    || (SubscriptionManager.getSimStateForSlotIndex(phoneId)
                    == TelephonyManager.SIM_STATE_LOADED))
                    && SubscriptionManager.isValidSubscriptionId(defaultDataSubId);
        }
        if (simAvailable) {
            state.value = getLteEnabled();
        } else {
            state.value = false;
        }
        Log.d(TAG, "handleUpdateState: state.value = " + state.value +
                " simAvailable = " + simAvailable + " mServiceForPhone " + mServiceForPhone);
        PrimarySubManager primarySubManager = PrimarySubManager.from(mContext);
        if (!simAvailable || isAirplaneModeOn() || isInCall()
                || Resources.getSystem().getInteger(com.android.internal.R.integer.simlock_restrict_networktype) != -1
                && primarySubManager != null
                && !primarySubManager.from(mContext).isWhiteListCard(phoneId)) {
            if (isSupportDualLTE()) {
                state.icon = getDualLTETileIcon();
            } else {
                state.icon = ResourceIcon.get(R.drawable.ic_qs_4g_ex);
            }
            state.state = Tile.STATE_UNAVAILABLE;
            return;
        } else {
            if (state.value) {
                if (isSupportDualLTE()) {
                    state.icon = getDualLTETileIcon();
                } else {
                    state.icon = ResourceIcon.get(R.drawable.ic_qs_4g_ex);
                }
                if (!isNetworkOptionAllowed() && mServiceForPhone == 1) {
                    state.state = Tile.STATE_INACTIVE;
                    state.contentDescription =  mContext.getString(
                            R.string.accessibility_quick_settings_lte_off);
                } else {
                    state.state = Tile.STATE_ACTIVE;
                    state.contentDescription =  mContext.getString(
                            R.string.accessibility_quick_settings_lte_on);
                }
            } else {
                if (isSupportDualLTE()) {
                    state.icon = getDualLTETileIcon();
                } else {
                    state.icon = ResourceIcon.get(R.drawable.ic_qs_4g_ex);
                }
                state.state = Tile.STATE_INACTIVE;
                state.contentDescription =  mContext.getString(
                        R.string.accessibility_quick_settings_lte_off);
            }
        }
        state.expandedAccessibilityClassName = Switch.class.getName();
    }

    @Override
    protected String composeChangeAnnouncement() {
        if (mState.value) {
            return mContext.getString(R.string.accessibility_quick_settings_lte_changed_on);
        } else {
            return mContext.getString(R.string.accessibility_quick_settings_lte_changed_off);
        }
    }

    @Override
    public int getMetricsCategory() {
        return QS_LTESERVICE;
    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())
                   || Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(intent.getAction())) {
                refreshState();
            }
        }
    };

    private boolean isAirplaneModeOn() {
        return Settings.Global.getInt(mContext.getContentResolver(),
                Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
    }

    private boolean isInCall() {
        return getTelecommManager().isInCall();
    }

    private TelecomManager getTelecommManager() {
        return (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
    }

    private boolean isSupportDualLTE() {
        return QSFactoryImpl.isDeviceSupportDualLte();
    }

    private int getSubId() {
        int[] subIds = SubscriptionManager.getSubId(mServiceForPhone);
        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        if (subIds != null && subIds.length >= 1) {
            subId = subIds[0];
        }
        return subId;
    }
}
